<template>
  <div class="menu-tree">
    <el-tree
      :data="menuTree"
      show-checkbox
      node-key="menuId"
      :default-expanded-keys="defaultExpandedKeys"
      :default-checked-keys="defaultCheckedKeys"
      @check="handleCheckChange"
      :props="{
        children: 'children',
        label: 'menuName',
        disabled: (data) => data.type === '2' // 操作类型的菜单不可选
      }"
    >
      <template v-slot="{ node, data }">
        <span class="custom-tree-node">
          <span>
            <i :class="data.icon ? data.icon : ''" v-if="data.icon"></i>
            {{ node.label }}
          </span>
          <span v-if="data.perms" class="menu-perms">{{ data.perms }}</span>
        </span>
      </template>
    </el-tree>
  </div>
</template>

<script>
export default {
  name: 'MenuTree',
  props: {
    // 默认选中的菜单ID列表
    checkedMenuIds: {
      type: Array,
      default: () => []
    },
    // 菜单类型过滤：0-目录，1-菜单，2-按钮
    menuTypes: {
      type: Array,
      default: () => ['0', '1'] // 默认可选目录和菜单
    }
  },
  data() {
    return {
      menuTree: [],
      defaultExpandedKeys: [],
      defaultCheckedKeys: [],
      loading: false
    }
  },
  watch: {
    checkedMenuIds: {
      handler(newVal) {
        this.defaultCheckedKeys = [...newVal]
        this.expandKeys()
      },
      immediate: true
    }
  },
  created() {
    this.loadMenuTree()
  },
  methods: {
    // 加载菜单树
    loadMenuTree() {
      this.loading = true
      const menuApi = require('@/api/menu').default
      menuApi.getMenuTree().then(res => {
        // 根据menuTypes过滤菜单
        if (this.menuTypes && this.menuTypes.length > 0) {
          this.menuTree = this.filterMenuByType(res.data, this.menuTypes)
        } else {
          this.menuTree = res.data
        }
        // 展开选中的节点
        this.expandKeys()
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    
    // 根据类型过滤菜单
    filterMenuByType(menuList, types) {
      return menuList.map(menu => {
        const newMenu = { ...menu }
        if (newMenu.children && newMenu.children.length > 0) {
          newMenu.children = this.filterMenuByType(newMenu.children, types)
        }
        // 如果子菜单全部被过滤掉，则清空children
        if (newMenu.children && newMenu.children.length === 0) {
          delete newMenu.children
        }
        return newMenu
      }).filter(menu => types.includes(menu.type))
    },
    
    // 展开选中节点
    expandKeys() {
      const expandedKeys = []
      
      const findParentKeys = (menuList, checkedKeys) => {
        menuList.forEach(menu => {
          if (checkedKeys.includes(menu.menuId)) {
            // 如果当前节点被选中，找到其所有父节点
            this.findParentIds(menu.menuId, expandedKeys)
          }
          if (menu.children && menu.children.length > 0) {
            findParentKeys(menu.children, checkedKeys)
          }
        })
      }
      
      findParentKeys(this.menuTree, this.defaultCheckedKeys)
      this.defaultExpandedKeys = expandedKeys
    },
    
    // 递归查找父节点ID
    findParentIds(menuId, result) {
      // 简单实现，实际应用中可能需要在菜单数据中维护parentId关系
      const findParent = (menuList, id) => {
        for (const menu of menuList) {
          if (menu.children && menu.children.length > 0) {
            const hasChild = menu.children.some(child => child.menuId === id)
            if (hasChild) {
              result.push(menu.menuId)
              // 继续查找上层父节点
              findParent(this.menuTree, menu.menuId)
              return true
            }
            if (findParent(menu.children, id)) {
              return true
            }
          }
        }
        return false
      }
      findParent(this.menuTree, menuId)
    },
    
    // 选中状态变化处理
    handleCheckChange(data, checked) {
      // 获取所有选中的节点ID
      const checkedKeys = checked.checkedKeys
      // 排除按钮类型的菜单
      const validKeys = checkedKeys.filter(key => {
        const node = this.findNodeById(this.menuTree, key)
        return !node || node.type !== '2'
      })
      
      this.$emit('change', validKeys)
    },
    
    // 根据ID查找节点
    findNodeById(menuList, id) {
      for (const menu of menuList) {
        if (menu.menuId === id) {
          return menu
        }
        if (menu.children && menu.children.length > 0) {
          const node = this.findNodeById(menu.children, id)
          if (node) {
            return node
          }
        }
      }
      return null
    },
    
    // 获取当前选中的菜单ID列表
    getCheckedKeys() {
      // 通过refs获取树组件实例
      const tree = this.$refs.menuTree
      if (tree) {
        return tree.getCheckedKeys()
      }
      return this.defaultCheckedKeys
    }
  }
}
</script>

<style scoped>
.menu-tree {
  max-height: 400px;
  overflow-y: auto;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.menu-perms {
  font-size: 12px;
  color: #909399;
  margin-left: 10px;
}
</style>